package com.ruleengine.container;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.apache.log4j.Logger;

import com.ruleengine.instruction.InstructionSet;
import com.ruleengine.parser.exception.RuleEngineParserException;
import com.ruleengine.task.factory.impl.DefaultWorkflowFactory;
import com.ruleengine.task.impl.WorkflowTask;
import com.ybt.configration.IYBTConfigration;
import com.ybt.configration.YBTConfigration;
import com.ybt.pub.Utils;

public class WorkflowContainerManager {
    private static WorkflowContainerManager manager;
    private static String CONFIG_DIR = "workflows";
    private static Logger logger = Logger
            .getLogger(WorkflowContainerManager.class);

    private WorkflowContainerManager() {
        CONFIG_DIR = YBTConfigration.getInstance().getProperty(
                IYBTConfigration.WORKFLOW_DEPLOY_PATH)
                + File.separator + CONFIG_DIR;
        loadFromLocal(CONFIG_DIR+ File.separator + "channel");
        loadFromLocal(CONFIG_DIR+ File.separator + "service");
    }

    public static WorkflowContainerManager getInstance() {
        if (manager == null) {
            manager = new WorkflowContainerManager();
        }
        return manager;
    }

    /**
     * 注册（新增）或更新工作流配置
     * 
     * @param taskConfig
     *            工作流配置
     * @param codeing
     *            编码类型
     * @throws ContainerException
     */
    public void registerWorkflow(InputStream taskConfig, String codeing)
            throws RuleEngineParserException {
        DefaultWorkflowFactory factory = new DefaultWorkflowFactory();
            WorkflowTask task = factory.createWorkflow(taskConfig, codeing);
            WorkflowContainer.getInstance().registerWorkflowTask(task);
    }

    /**
     * 注册（新增）或更新工作流配置，默认采用 UTF-8解析配置
     * 
     * @param taskConfig
     *            使用UTF-8编码的工作流配置
     * @throws ContainerException
     */
    public void registerWorkflow(InputStream taskConfig)
            throws RuleEngineParserException {
        registerWorkflow(taskConfig, "UTF-8");
    }

    /**
     * 注册（新增）或更新工作流任务配置.
     * 
     * @param taskConfig
     *            工作流配置
     * @throws ContainerException
     */
    public void registerWorkflow(String taskConfig, String codeing)
            throws RuleEngineParserException {
            ByteArrayInputStream stream;
            try {
                stream = new ByteArrayInputStream(taskConfig
                        .getBytes("UTF-8"));
            } catch (UnsupportedEncodingException e) {
                throw new RuleEngineParserException(e);
            }
            registerWorkflow(stream, "UTF-8");
    }

    /**
     * 删除工作流任务配置.<p>删除工作流任务配置，
     * 将导致相对应的工作流指令集一起删除.
     * @param taskId
     *            工作流配置ID
     * @return 删除后的工作流任务配置
     * @throws ContainerException
     */
    public WorkflowTask removeWorkflow(String taskId) throws RuleEngineParserException {
        return WorkflowContainer.getInstance().removeWorkflowTask(taskId);
    }

    /**
     * 获取工作流任务（WorkflowTask）配置.
     * 
     * @param taskId
     *            工作流任务配置id
     * @return 工作流任务配置
     */
    public WorkflowTask getWorkflowTask(String taskId) {
        return WorkflowContainer.getInstance().getWorkflowTask(taskId);
    }
    
    
    /**
     * 获取工作流指令.
     * 工作流指令（WorkflowInstruction）是工作流任务（WorkflowTask）配置信息的运行时表现.
     * 通过编译工作流任务（WorkflowTask）得到优化后的工作流指令（WorkflowInstruction）
     * 
     * @param taskId
     *            工作流任务配置id
     * @return 工作流指令集
     */
    public InstructionSet getWorkflowInstruction(String taskId) {
        return WorkflowContainer.getInstance().getWorkflowInstruction(taskId);
    }

    private void loadFromLocal(String dirPath) {
        File dir = new File(dirPath);
        if (!dir.exists()) {
            dir.mkdirs();
        }

        File[] connFiles = dir.listFiles(new FilenameFilter() {
            public boolean accept(File arg0, String arg1) {
                // TODO Auto-generated method stub
                if (arg1.matches("(.)*\\.xml"))
                    return true;
                return false;
            }
        });

        if (connFiles == null || connFiles.length == 0) {
            // 没有配置文件
            logger.debug("there is no workflow configration files in direct : "
                    + dirPath);
            return;
        }

        // 逐个处理workflow配置文件
        for (File connFile : connFiles) {
            // 注册connector
            InputStream s = null;
            try {
                s = new FileInputStream(connFile);
                registerWorkflow(s);
                Utils.copyFile(connFile, dirPath + File.separator
                        + "autobak");
            } catch (Exception e) {
                logger.error(e, e);
            } finally {
                if (s != null) {
                    try {
                        s.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        logger
                                .error(
                                        "close file error when load workflows from local disk",
                                        e);
                    }
                }
            }
        }
    }

    public static void main(String[] args){
        //Object o = WorkflowContainerManager.getInstance().getWorkflowInstruction("icbc", "newCont");
        //System.out.println(o);
    }
}
